package cn.ipenta.app.controller;

import cn.ipenta.blockchain.BlockChainClient;
import cn.ipenta.blockchain.BlockChainException;
import cn.ipenta.blockchain.entity.*;
import hprose.client.HproseHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.*;

/**
 * @author ipenta
 * @ClassName: IndexController
 * @Description: TODO
 * @date 2017-09-25 下午10:30
 */
@Controller
public class HomeController {

	private static final String CIRCULATIONS = "circulations";
	private static final String INOCULATIONS = "inoculationz";
	private static final String VACCINE_ID = "VACCINE_ID";

	private final static Long DEFAULT_PAGE_COUNT = 50L;
	private final static Integer DEFAULT_SORT_TYPE = 1;

	private final BlockChainClient blockChainClient;

	@Autowired
	public HomeController(HproseHttpClient hproseHttpClient) {
		this.blockChainClient = hproseHttpClient.useService(BlockChainClient.class);
	}


	@GetMapping("/home")
	public String index(Map<String, Object> map) {

		List<TransactionInfo> transactionInfoList = new ArrayList<>();

		long blockHeight = messageConverter(blockChainClient.lookupBlockHeight());

		List<BlockOverviewInfo> blockOverviewInfoList = messageConverter(blockChainClient.lookupBlockOverviewTop(5L));

		List<BlockInfo> blockInfoList = messageConverter(blockChainClient.lookupBlockListByHeight(blockHeight - 5, blockHeight));

		for (BlockInfo blockInfo : blockInfoList) {
			transactionInfoList.addAll(blockInfo.getTransactions());
		}

		map.put("blockHeight", blockHeight);
		map.put("blockOverviewInfoList", blockOverviewInfoList);
		map.put("transactionInfoList", transactionInfoList);

		return "app/index";
	}

	@GetMapping("/chain/overview")
	public String overviewChain(@RequestParam(required = false) Long height,
								@RequestParam(required = false) Long current,
								@RequestParam(required = false) Long pageCount,
								@RequestParam(required = false) Integer sortType,
								Map<String, Object> map) {

		if (null == height) {

			if (null == current) {
				current = 1L;
			}
			if (null == pageCount) {
				pageCount = DEFAULT_PAGE_COUNT;
			}
			if (null == sortType) {
				sortType = DEFAULT_SORT_TYPE;
			}

			List<BlockOverviewInfo> blockOverviewInfoList = messageConverter(blockChainClient.lookupBlockOverviewGroup(current, pageCount, sortType));
			map.put("blockOverviewInfoList", blockOverviewInfoList);
			return "app/chain/overview";

		}

		BlockOverviewInfo blockOverviewInfo = messageConverter(blockChainClient.lookupBlockOverviewByHeight(height));
		BlockInfo blockInfo = messageConverter(blockChainClient.lookupBlockByHeight(height));
		map.put("blockOverviewInfo", blockOverviewInfo);
		map.put("transactions", blockInfo.getTransactions());

		return "app/chain/overview";
	}

	@GetMapping("/tx")
	public String overviewTx(@RequestParam String hash,
							 Map<String, Object> map) {
		TransactionInfo transactionInfo  =	messageConverter(blockChainClient.lookupTxByHash(hash));
		map.put("transactionInfo", transactionInfo);

		return "app/tx/overview";
	}

	@GetMapping("/tx/record")
	public String record(@RequestParam String vaccineId,
						 Map<String, Object> map) {
		map.put("records",findRecord(vaccineId));
		return "app/tx/record";
	}

	/**
	 *查询记录
	 *
	 * */
	private List<TreeMap<String,Object>> findRecord(String vaccineId) {
		List<TreeMap<String,Object>> treeMapList = new ArrayList<>();

		Map<String,String> filter = new HashMap<>();
		filter.put(VACCINE_ID,vaccineId);
		List<TransactionInfo> inoculations = messageConverter(blockChainClient.lookupTxByKey(INOCULATIONS, filter));
		List<TransactionInfo> circulations = messageConverter(blockChainClient.lookupTxByKey(CIRCULATIONS, filter));
		for (TransactionInfo transactionInfo: circulations){
			RecordInfo recordInfo =  transactionInfo.getContentInfo();
			treeMapList.add(recordInfo.getRecordContent());
		}
		for (TransactionInfo transactionInfo: inoculations){
			RecordInfo recordInfo =  transactionInfo.getContentInfo();
			treeMapList.add(recordInfo.getRecordContent());
		}

		return treeMapList;
	}

	// 数据转换
	private <T> T messageConverter(Message<T> message) {
		if (message.getStatus().equals(Message.Status.SUCCESS.getValue())) {
			return message.getData();
		} else {
			throw new BlockChainException(message.getErrorContent());
		}
	}
}
